ECS(Fargate)上にLocustとAPIサーバ(Go)を構築してService Connectで接続してみた

ECS(Fargate)上にLocustとAPIサーバ(Go)を構築してService Connectで接続してみた

Clock Icon2024.09.05

こんにちは、ゲームソリューション部のsoraです。
今回は、ECS(Fargate)上にLocustとAPIサーバ(Go)を構築してService Connectで接続してみたことについて書いていきます。

イメージの作成

LocustとLocustのリクエスト先のAPIサーバのイメージを作成します。

Locust

Locustのdockerfileは以下です。

/locust/dockerfile
FROM locustio/locust

WORKDIR /locust

# Locustのシナリオファイルを配置
COPY locustfile.py /locust/locustfile.py

# Locustのシナリオを実行
CMD ["-f", "/locust/locustfile.py"]

Locustで実行するシナリオファイルは以下です。
LocustのシナリオはPythonで記述します。
ルートパスにGETリクエストを送る単純なタスクになっています。

/locust/locustfile.py
from locust import HttpUser, task, between

class QuickstartUser(HttpUser):
    wait_time = between(1, 2.5)

    @task
    def index_page(self):
        self.client.get("/")

APIサーバ

Locustからリクエストを受けるAPIサーバを構築します。
言語はGoで、ポート8080でアクセスがあった場合に、Hello, Locust!を返すようにしています。

/go-api/dockerfile
FROM golang:alpine

WORKDIR /app

RUN apk update && apk add --no-cache git

COPY /src .
RUN go mod init app
RUN go mod tidy

CMD ["go", "run", "main.go"]
/go-api/src/main.go
package main

import (
	"fmt"
	"log"
	"net/http"
)

// ハンドラ関数を定義する
func helloHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Hello, Locust!")
}

func main() {
	// ルートエンドポイントにハンドラ関数を設定
	http.HandleFunc("/", helloHandler)

	// サーバーを起動する
	port := "8080"
	fmt.Printf("Server is running on port %s\n", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}

上記イメージを作成して、ECRにプッシュします。

# Locust
docker build -t locust .
docker tag locust:latest xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/soratest:locust

# API
docker build -t go-api .
docker tag go-api:latest xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/soratest:go-api

## ECRへプッシュ
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com
docker push xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/soratest:locust
docker push xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/soratest:go-api

ECSタスク定義

2つのイメージでそれぞれタスク定義を作成します。
ポートマッピングをLocustは8089、APIサーバは8080に設定するぐらいで、他はデフォルトの設定です。
テストのためログ収集はなしにしています。
詳細な手順は割愛します。

ECSクラスタ作成・サービス作成

ECSのクラスタを作成して、同じクラスタにLocustとAPIサーバの2サービスを作成します。

サービス作成時にService Connectをオンにします。
LocustはパブリックIPアドレスを付与して外部からの通信が発生するものの、Service Connectのエンドポイントを提供してリクエストを受けるわけではないため「クライアント側のみ」、APIサーバはLocustからService Connectを通じての接続があるため「クライアントとサーバ」に設定します。
APIサーバは「クライアントとサーバー」で設定するため、サービス接続としてポート8080を指定します。

名前空間として、クラスタ作成時に作成されたものを使用するか、Cloud Mapにて作成したものを使用して、2サービスに同じ名前空間を設定します。
sr-ecs-locust-api02
sr-ecs-locust-api01

接続確認

クラスタ内に2つのサービスがそれぞれ起動できたため、LocustからAPIサーバにリクエストを投げてみます。
http://{タスクのPublic IPアドレス}:8089に接続するとLocustの画面が表示されました。
sr-ecs-locust-api03
HostにAPIサーバのService Connectのエンドポイントを指定すると、正常にアクセスできていることが確認できました。
※キャプチャは違うシナリオで実行したときのもののため、/aboutもあります
sr-ecs-locust-api04
sr-ecs-locust-api05

参考

https://dev.classmethod.jp/articles/try-amazon-ecs-service-connect/

最後に

今回は、ECS(Fargate)上にLocustとAPIサーバ(Go)を構築してService Connectで接続してみたことを記事にしました。
どなたかの参考になると幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.